package com.wwdx.service.impl;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageDecoder;
import com.wwdx.BaseCommons;
import com.wwdx.model.WwdxBookModel;
import com.wwdx.service.WechatPublishServiceI;
import com.wwdx.utils.ConstantHolder;
import com.wwdx.utils.QrCodeUtil;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpQrcodeService;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage;
import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.List;

/**
 * @author liguoliang
 * @date 2018/1/15 11:17
 */
@Service
public class WechatPublishServiceImpl extends BaseCommons implements WechatPublishServiceI {

    @Override
    public void sendCard(WxMpUser wxMpUser,int cardCount,int bookCount,WxMpService service) throws WxErrorException{
        List<WwdxBookModel> wwdxBookModels = wwdxBookService.selectModelList(WwdxBookModel.builder().ishost(1).status(0).type(0).build(), 1, 1);
        WwdxBookModel wwdxBookModel = wwdxBookModels.get(0);
        String card = "/data/wwdx/static/pullxin/card.jpg",  headimg = wxMpUser.getHeadImgUrl(),
                bookimg = "/data/wwdx/static/cover/"+wwdxBookModel.getBookimg(), date = new DateTime().toString("HH:mm"),
                content = wwdxBookModel.getContentsummary(), outPath = "/data/wwdx/static/pullxin/"+wxMpUser.getUnionId()+".jpg";
        this.generalImgFile(card, headimg, bookimg, date, String.valueOf(cardCount), String.valueOf(bookCount), content, outPath);
        WxMediaUploadResult imageMedia = service.getMaterialService().mediaUpload(WxConsts.MediaFileType.IMAGE, new File(outPath));
        WxMpKefuMessage message = new WxMpKefuMessage();
        message.setMsgType(WxConsts.KefuMsgType.IMAGE);
        message.setToUser(wxMpUser.getOpenId());
        message.setMediaId(imageMedia.getMediaId());
        service.getKefuService().sendKefuMessage(message);
    }

    @Override
    public void sendCard(WxMpUser wxMpUser, WxMpService service) throws WxErrorException {
        String card = "/data/wwdx/static/pullxin/placard.jpg",  headimg = wxMpUser.getHeadImgUrl(),
                nickname=wxMpUser.getNickname(),recommend = "HI,我是蜜读馆长"+nickname,openId = wxMpUser.getOpenId(),
                outPath = "/data/wwdx/static/pullxin/"+wxMpUser.getUnionId()+1+".jpg";
        this.generalImgFile(card,headimg,recommend,openId,outPath);
        WxMediaUploadResult imageMedia = service.getMaterialService().mediaUpload(WxConsts.MediaFileType.IMAGE, new File(outPath));
        WxMpKefuMessage message = new WxMpKefuMessage();
        message.setMsgType(WxConsts.KefuMsgType.IMAGE);
        message.setToUser(wxMpUser.getOpenId());
        message.setMediaId(imageMedia.getMediaId());
        service.getKefuService().sendKefuMessage(message);
    }

    /**
     * 生成文字图片
     * @param card 背景图
     * @param headimg 头像
     * @param bookimg 书籍图片
     * @param date 日期
     * @param cardCount 打卡次数
     * @param bookCount 书籍数
     * @param content 书籍介绍
     * @param outPath 输出路径
     */
    private void generalImgFile(String card, String headimg, String bookimg,String date,
                                String cardCount,String bookCount,String content,String outPath) {
        //主图片的路径
        try (InputStream is = new FileInputStream(card)){
            //通过JPEG图象流创建JPEG数据流解码器
            JPEGImageDecoder jpegDecoder = JPEGCodec.createJPEGDecoder(is);
            //解码当前JPEG数据流，返回BufferedImage对象
            BufferedImage buffImg = jpegDecoder.decodeAsBufferedImage();
            //得到画笔对象
            Graphics g = buffImg.getGraphics();

            //头像
            BufferedImage headImg = ImageIO.read(new URL(headimg));
            BufferedImage bi2 = new BufferedImage(headImg.getWidth(), headImg.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
            Ellipse2D.Double shape = new Ellipse2D.Double(0, 0, headImg.getWidth(), headImg.getHeight());
            Graphics2D g2 = bi2.createGraphics();
            g2.setClip(shape);
            g2.drawImage(headImg, 0, 0,null);
            g2.setBackground(Color.green);
            g2.dispose();
            g.drawImage(bi2, 300, 60, null);

            //书籍图片
            ImageIcon bookimgIcon = new ImageIcon(bookimg);
            Image bookImg = bookimgIcon.getImage();
            g.drawImage(bookImg, 260, 350,bookimgIcon.getIconWidth() / 3, bookimgIcon.getIconHeight() / 3, null);

            //时间文字写入
            g.setColor(Color.BLACK);
            g.setFont(new Font("微软雅黑", Font.PLAIN, 35));
            g.drawString(date, 320, 250);
            //打卡次数写入
            String word;
            String cardContent = "早起天     ";
            String bookContent = "听书本";
            g.setColor(Color.RED);
            g.setFont(new Font("微软雅黑", Font.PLAIN, 30));
            switch (cardCount.length()){
                case 1:
                    word = cardContent.substring(0, 2) + "    " + cardContent.substring(2);
                    g.drawString(cardCount, 290, 300);
                    g.setColor(Color.GRAY);
                    g.drawString(word, 220, 300);
                    this.generalBookWords(g,bookCount,bookContent);
                    break;
                case 2:
                    word = cardContent.substring(0, 2) + "      " + cardContent.substring(2);
                    g.drawString(cardCount, 270, 300);
                    g.setColor(Color.GRAY);
                    g.drawString(word, 200, 300);
                    this.generalBookWords(g,bookCount,bookContent);
                    break;
                case 3:
                    word = cardContent.substring(0, 2) + "        " + cardContent.substring(2);
                    g.drawString(cardCount, 250, 300);
                    g.setColor(Color.GRAY);
                    g.drawString(word, 180, 300);
                    this.generalBookWords(g,bookCount,bookContent);
                    break;
                default:
                    break;
            }
            //书籍简介文字写入
            StringBuilder sb = new StringBuilder();
            //书籍文字字数不能超过3行
            int count = 0 ,ctnum = 3;
            for (int i = 0; i < content.length(); i++) {
                sb.append(content.charAt(i));
                if (count == ctnum){
                    break;
                }
                if (i > 0 && i % 15 == 0) {
                    g.setColor(Color.black);
                    g.setFont(new Font("微软雅黑", Font.PLAIN, 30));
                    g.drawString(sb.toString(), 120, 650 + i * 2);
                    sb.setLength(0);
                    count ++;
                }
            }
            if (count < ctnum && sb.length() > 0){
                g.setColor(Color.BLACK);
                g.setFont(new Font("微软雅黑", Font.PLAIN, 30));
                g.drawString(sb.toString(), 120, 650 + 45 * 2);
                sb.setLength(0);
            }
            g.dispose();
            ImageIO.write(buffImg, "jpg", new File(outPath));
        }catch (IOException e){
            logger.error("错误信息：{}",e.getMessage());
        }
    }

    /**
     * 生成海报图片
     * @param card 背景图
     * @param headimg 头像
     * @param recommend 昵称
     * @param openId 昵称
     */
    private void generalImgFile(String card, String headimg, String recommend,String openId,String outPath) {
        try {
            BufferedImage buffImg = ImageIO.read(new FileInputStream(card));
            //头像
            Graphics graphics = buffImg.getGraphics();
            BufferedImage headImg = ImageIO.read(new URL(headimg));
            BufferedImage bi2 = new BufferedImage(90, 90, BufferedImage.TYPE_4BYTE_ABGR);
            Ellipse2D.Double shape = new Ellipse2D.Double(0, 0, 90, 90);
            Graphics2D g2 = bi2.createGraphics();
            g2.setClip(shape);
            g2.drawImage(headImg, 0, 0,90,90,null);
            graphics.drawImage(bi2, 286, 43, 90,90,null);

            //欢迎语文字
            Graphics2D graphics1 = buffImg.createGraphics();
            graphics1.setColor(Color.decode("#fff0c4"));
            Font font = new Font("微软雅黑", Font.PLAIN, 34);
            graphics1.setFont(font);
            //失真处理
            graphics1.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            graphics1.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
            // 计算文字长度，计算居中的x点坐标
            FontMetrics fm = graphics1.getFontMetrics(font);
            int textWidth = fm.stringWidth(recommend);
            int widthX = (buffImg.getWidth() - textWidth) / 2;
            graphics1.drawString(recommend, widthX, 170);

            //二维码
            String redirectURI = wechatUrl+"auth.html?url="+wechatUrl+"index.html?merchantId="+openId;
            BufferedImage image = QrCodeUtil.createImage(redirectURI, null, false);
            Graphics graphics2 = buffImg.getGraphics();
            graphics2.drawImage(image,263,488,132,132,null);
            graphics.dispose();
            graphics1.dispose();
            graphics2.dispose();
            ImageIO.write(buffImg, "jpg", new File(outPath));
        } catch (Exception e) {
            logger.error("错误信息：{}",e.getMessage());
        }
    }

    private void generalBookWords(Graphics g,String bookCount,String bookContent){
        //书籍数写入
        String bookWord = "";
        switch (bookCount.length()){
            case 1:
                bookWord = bookContent.substring(0, 2) + "    " + bookContent.substring(2);
                break;
            case 2:
                bookWord = bookContent.substring(0, 2) + "      " + bookContent.substring(2);
                break;
            case 3:
                bookWord = bookContent.substring(0, 2) + "        " + bookContent.substring(2);
                break;
            default:
                break;
        }
        g.setColor(Color.RED);
        g.drawString(bookCount, 455, 300);
        g.setColor(Color.GRAY);
        g.drawString(bookWord, 385, 300);
    }

    @Override
    public String getQrcodeUrl(String sources,WxMpService service){
        String key = String.format(ConstantHolder.QRCODE_TICKET, sources);
        String ticket = (String) valueOperations.get(key);
        WxMpQrcodeService qrcodeService = service.getQrcodeService();
        try {
            if (StringUtils.isBlank(ticket)){
                WxMpQrCodeTicket wxMpQrCodeTicket = qrcodeService.qrCodeCreateLastTicket(sources);
                ticket = wxMpQrCodeTicket.getTicket();
                valueOperations.set(key,ticket);
            }
            return service.shortUrl(qrcodeService.qrCodePictureUrl(ticket));
        }catch (WxErrorException e){
            logger.error("错误信息：{}",e.getMessage());
            return null;
        }
    }
}